package com.nl.controller.web.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.nl.controller.common.model.BaseResult;


/**
 * desc:
 * 
 * @author  sj
 * @version createtime: 2019年3月11日 上午11:01:56
 */
public class HttpClientUtil {
    
    private static RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(20000)
            .setConnectionRequestTimeout(20000)
            .setSocketTimeout(20000).build();
    
    
    public static BaseResult<String> sendGet(String url,Map<String, String> querys,String charset,Map<String,String> headers){
        HttpGet httpGet = new HttpGet(buildUrl(url,querys));
        httpGet.setConfig(requestConfig);
        if(headers!=null){
            for (Entry<String, String> entry : headers.entrySet()) {  
                httpGet.setHeader(entry.getKey(), entry.getValue());  
            }  
        }
        return sendGet(httpGet,charset);
    }
    
    public static BaseResult<String> sendPost4xml(String url,String reqXml,String charset,Map<String,String> headers) throws UnsupportedEncodingException{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        if(headers!=null){
            for (Entry<String, String> entry : headers.entrySet()) {  
                httpPost.setHeader(entry.getKey(), entry.getValue());  
            }  
        }
        httpPost.setHeader("Content-Type","text/xml;charset="+charset);
        StringEntity stringEntity = new StringEntity(reqXml,charset);
        httpPost.setEntity(stringEntity);
        return sendPost(httpPost,charset);
    }
    
    public static BaseResult<String> sendPost4Json(String url,String jsonString,String charset,Map<String,String> headers) throws UnsupportedEncodingException{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        if(headers!=null){
            for (Entry<String, String> entry : headers.entrySet()) {  
                httpPost.setHeader(entry.getKey(), entry.getValue());  
            }  
        }
        StringEntity stringEntity = new StringEntity(jsonString,charset);
        stringEntity.setContentEncoding(charset);
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity);
        return sendPost(httpPost,charset);
    }
    
    /**
     * 
     * desc:
     * @author sj
     * @date 2019年3月11日 上午11:35:46
     * @param url
     * @param params key1=value1&key2=value2
     * @param head
     * @return
     * @throws UnsupportedEncodingException 
     */
    public static BaseResult<String> sendPost4Form(String url,String params,String charset,Map<String,String> headers) throws UnsupportedEncodingException{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        if(headers!=null){
            for (Entry<String, String> entry : headers.entrySet()) {  
                httpPost.setHeader(entry.getKey(), entry.getValue());  
            }  
        }
        StringEntity stringEntity = new StringEntity(params,charset);
        stringEntity.setContentType("application/x-www-form-urlencoded");
        httpPost.setEntity(stringEntity);
        return sendPost(httpPost,charset);
    }
    
    
    /**
     * 
     * desc:
     * @author sj
     * @date 2019年3月11日 下午2:19:51
     * @param url
     * @param maps
     * @param charset
     * @param headers
     * @return
     */
    public static BaseResult<String> sendPost4Form(String url,Map<String, String> maps,String charset,Map<String,String> headers){
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        if(headers!=null){
            for (Entry<String, String> entry : headers.entrySet()) {  
                httpPost.setHeader(entry.getKey(), entry.getValue());  
            }  
        }
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        if(maps!=null){
            for (String key : maps.keySet()) {
                nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
            }
        }
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, charset));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return sendPost(httpPost,charset);
    }
    
    
    
    private static BaseResult<String> sendPost(HttpPost httpPost,String charset){
        BaseResult<String> result = BaseResult.newFailInstance();
        CloseableHttpClient httpClient=null;
        CloseableHttpResponse response=null;
        HttpEntity httpEntity=null;
        try {
            httpClient = HttpClients.createDefault();
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if(statusCode!=HttpStatus.SC_OK){
                result.setRetCode(String.valueOf(statusCode));
                result.setRetMsg("HTTP ERROR HttpStatus: "+ response.getStatusLine());
            }else{
                httpEntity = response.getEntity();
                if(httpEntity!=null){
                    result.setRetCode("0");
                    result.setData(EntityUtils.toString(httpEntity, charset));
                }else{
                    result.setRetCode(String.valueOf(statusCode));
                    result.setRetMsg("消息内容为空");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setRetCode("-99");
            result.setRetMsg(" httpPost error: "+e.getMessage());
        } finally{
            if(response!=null){
                try {
                    EntityUtils.consume(response.getEntity());
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(httpPost!=null && !httpPost.isAborted()){
                httpPost.releaseConnection();
                httpPost.abort();
            }
            if(httpClient!=null){
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    
    private static BaseResult<String> sendGet(HttpGet httpGet,String charset){
        BaseResult<String> result = BaseResult.newFailInstance();
        CloseableHttpClient httpClient=null;
        CloseableHttpResponse response=null;
        HttpEntity httpEntity=null;
        try {
            httpClient = HttpClients.createDefault();
            response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if(statusCode!=HttpStatus.SC_OK){
                result.setRetCode(String.valueOf(statusCode));
                result.setRetMsg("HTTP ERROR HttpStatus: "+ response.getStatusLine());
            }else{
                httpEntity = response.getEntity();
                if(httpEntity!=null){
                    result.setRetCode("0");
                    result.setData(EntityUtils.toString(httpEntity, charset));
                }else{
                    result.setRetCode(String.valueOf(statusCode));
                    result.setRetMsg("消息内容为空");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setRetCode("-99");
            result.setRetMsg(" httpPost error: "+e.getMessage());
        } finally{
            if(response!=null){
                try {
                    EntityUtils.consume(response.getEntity());
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(httpGet!=null && !httpGet.isAborted()){
                httpGet.releaseConnection();
                httpGet.abort();
            }
            if(httpClient!=null){
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    
    private static String buildUrl(String url, Map<String, String> querys) {
        StringBuilder sbUrl = new StringBuilder();
        if (!StringUtils.isBlank(url)) {
            sbUrl.append(url);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        try {
                            sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }
        return sbUrl.toString();
    }
}

